# m3u txt json 都是 文本
# ts：一种封装的格式，它的全称为 MPEG2-TS。
# TS流：是将视频、音频、PSI等数据打包成传输包进行传送，主要用于节目传输
# 一般视频网站实况
# 用户上传 --> 对视频进行转码（可以转为 2k，4k，1080等） --> 切片处理
# 需要一个文件(m3u8)记录 切片的视频块顺序、分辨率等信息
# 抓取视频套路
# 1.找到m3u8文件（各种手段）
'''
    目前网站在网页源代码找不到m3u8的url
    1.在抓包工具直接会有ts文件，但不能用
    2.ts文件又被进一步js加密成png文件
'''
# 2.通过m3u8下载ts文件
# 3.通过各种手段把ts文件合并为一个mp4文件
import time
import requests
from bs4 import BeautifulSoup
import asyncio
import aiofiles
import aiohttp
import re
import os
from subprocess import Popen, PIPE, STDOUT
from selenium.webdriver import Edge


def get_m3u8_src(url):
    resp2 = requests.get(url)
    # print(resp2.text)
    obj = re.compile(r'var main = "(?P<m3u8_src>.*?)";.*?',re.S)
    m3u8_src = obj.search(resp2.text).group('m3u8_src')
    # print(m3u8_src)
    return m3u8_src

def get_iframe_src(url):
    resp = requests.get(url)
    # print(resp.text)
    obj = BeautifulSoup(resp.text,'html.parser')
    iframe_src = obj.find('iframe',attrs={'width':"100%"}).get('src')
    # print(iframe_src)
    return iframe_src

def download_m3u8(url,name):
    resp3 = requests.get(url)
    with open(f'./m3u8_file/{name}', mode='wb') as f:
        f.write(resp3.content)

async def download_png_jpg(url,name,session):
    async with session.get(url) as resp:
        async with aiofiles.open(f'./download_file/{name}',mode='wb') as f:
            await f.write(await resp.content.read())
            print(f'{name}  下载完成！')

async def create_tasks():
    tasks = []
    async with aiohttp.ClientSession() as session:
        async with aiofiles.open('m3u8_file/第二层m3u8地址', mode='r', encoding='utf-8') as f:
            async for line in f:    # IO操作
                if line.startswith('#'):
                    continue
                else:
                    png_jpg = line.strip()
                    name = png_jpg.split('/')[-1]
                    tasks.append(asyncio.create_task(download_png_jpg(png_jpg,name,session)))
                await asyncio.wait(tasks)

def run_bat(path,bat_name):
    fold_address = path
    os.chdir(fold_address)
    p = Popen("cmd.exe /c" + fold_address + bat_name, stdout=PIPE, stderr=STDOUT)

    curline = p.stdout.readline()
    # b''或 ''
    while (curline != b''):
        curline = p.stdout.readline()
    p.wait()

def merge_ts():
    lst = []
    n = ""
    with open("m3u8_file/第二层m3u8地址", mode="r", encoding='utf-8') as f:
        for line in f:
            if line.startswith('#'):
                continue
            else:
                png_jpg = line.strip()
                name = png_jpg.split('/')[-1]
                name = name.split(".")[0]
                name = name + ".ts"
                lst.append(f"{name}")
        for i in lst:
            n = n + "+" + i
        n = n.lstrip("+")
    with open("download_file/转换视频.bat", mode="w", encoding="utf-8") as f:
        f.write("ren *.png *.ts\n"
                "ren *.jpg *.ts")
    with open("download_file/合并视频.bat", mode="w", encoding="utf-8") as f:
        f.write(f"copy /b {n} movie.mp4\n"
                f"@echo off\n" 
                f"D:\n"
                f"python D:/Pycharm/project/PythonCrawler/Crawl_video_asynchronously/ts.py\n"
                f"pause\n"
                f"exit\n")
    # 运行批处理文件
    run_bat("D:/Pycharm/project/PythonCrawler/Crawl_video_asynchronously/download_file", "./转换视频.bat")
    time.sleep(2)
    run_bat("D:/Pycharm/project/PythonCrawler/Crawl_video_asynchronously/download_file", "./合并视频.bat")

    print("over !(>@<)")

def main():
    web = Edge()
    web.get("https://www.ai66.cc/")

    url = str(input("输入视频网址: "))
    # 得到iframe框架里的src
    iframe_src = get_iframe_src(url)
    # iframe_src = 'https://new.qqaku.com/share/1LBjUFU0LALFrbBq'  # 为了测试
    # # 拿到第一层m3u8的下载地址
    m3u8_src = get_m3u8_src(iframe_src)
    m3u8_src = iframe_src.split('share')[0] + m3u8_src.lstrip('/')
    download_m3u8(m3u8_src,'第一层m3u8地址')
    print('第一层m3u8地址下载完毕')
    with open('./m3u8_file/第一层m3u8地址', mode='r', encoding='utf-8') as f:
        for line in f:
            if line.startswith('#'):
                continue
            else:
                m3u8_src2 = line.strip()
    m3u8_src2 = iframe_src.split('share')[0] + m3u8_src2.lstrip('/')
    # print(m3u8_src2)
    download_m3u8(m3u8_src2,'第二层m3u8地址')
    print('第二层m3u8地址下载完毕')
    asyncio.run(create_tasks())
    # 合并视频
    merge_ts()

if __name__ == '__main__':
    main()

